package com.example.recall_application.mvp.presenter;

import android.Manifest;
import android.app.Application;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.database.ContentObserver;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.blankj.utilcode.util.SPUtils;
import com.example.recall_application.R;
import com.example.recall_application.app.Constants;
import com.example.recall_application.app.utils.RxHelper;
import com.example.recall_application.app.utils.RxUtils;
import com.example.recall_application.mvp.adapter.BaseAdapter;
import com.example.recall_application.mvp.contract.ConfigContract;
import com.example.recall_application.mvp.contract.MainContract;
import com.example.recall_application.mvp.entity.Config;
import com.example.recall_application.mvp.entity.ConfigRequest;
import com.example.recall_application.mvp.entity.EventBusPhone;
import com.example.recall_application.mvp.entity.EventBusPhoneErrorLog;
import com.example.recall_application.mvp.entity.EventBusPhonePRMN;
import com.example.recall_application.mvp.entity.WxUserInfo;
import com.example.recall_application.mvp.incomingcall.PhoneListener;
import com.example.recall_application.mvp.ui.activity.ConfigActivity;
import com.example.recall_application.mvp.ui.activity.ContacksActivity;
import com.example.recall_application.utils.CallLogHelper;
import com.example.recall_application.utils.ContactsUtils;
import com.example.recall_application.utils.PhoneUtil;
import com.example.recall_application.utils.SimHelper;
import com.example.recall_application.utils.SmsHelper;
import com.example.recall_application.utils.SystemUtils;
import com.example.recall_application.utils.TimeUtils;
import com.jess.arms.di.scope.ActivityScope;
import com.jess.arms.http.imageloader.ImageLoader;
import com.jess.arms.integration.AppManager;
import com.jess.arms.mvp.BasePresenter;
import com.jess.arms.utils.PermissionUtil;
import com.tbruyelle.rxpermissions2.RxPermissions;

import org.simple.eventbus.EventBus;
import org.simple.eventbus.Subscriber;
import org.simple.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import me.jessyan.rxerrorhandler.core.RxErrorHandler;
import me.jessyan.rxerrorhandler.handler.ErrorHandleSubscriber;
import okhttp3.ResponseBody;


/**
 * ================================================
 * Description:
 * <p>
 * Created by MVPArmsTemplate on 11/18/2019 14:46
 * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
 * <a href="https://github.com/JessYanCoding">Follow me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms/wiki">See me</a>
 * <a href="https://github.com/JessYanCoding/MVPArmsTemplate">模版请保持更新</a>
 * ================================================
 */
@ActivityScope
public class MainPresenter extends BasePresenter<MainContract.Model, MainContract.View> {
    @Inject
    RxErrorHandler mErrorHandler;
    @Inject
    Application mApplication;
    @Inject
    ImageLoader mImageLoader;
    @Inject
    AppManager mAppManager;
    public static Config config_p;
    public static String uuid = SPUtils.getInstance().getString(Constants.uuid);
    public static ArrayList<String> mData = new ArrayList<>();
    private ArrayList<String> callLog = new ArrayList<>();
    ContentResolver resolver = null;
    Uri uri_contact;
    Uri uri_call;
    Uri uri_sms;
    Uri uri_sms_box;
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(msg.what == 100002 && !mData.contains("通话记录:")){
                mData.add("通话记录:");
            }
            else if(msg.what == 100003 && !mData.contains("通讯录:")){
                mData.add("通讯录:");
            }
            else if(msg.what == 100001 && !mData.contains("短信:")){
                mData.add("短信:");
            }
            // callLog.addAll((Collection<? extends String>) msg.obj);
            callLog.clear();
            mData.addAll((Collection<? extends String>) msg.obj);
            for (int i = 0; i < mData.size(); i++) {
                callLog.add(PhoneUtil.handlePhone(mData.get(i)));
            }
            mData.clear();
            mData.addAll(callLog);
            removeDuplicate(mData);
        }
    };

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Inject
    public MainPresenter(MainContract.Model model, MainContract.View rootView) {
        super(model, rootView);
    }


    /**
     * 监听content变化
     */
    public void listenerContent(){
        try{
            observer observer = new observer(new Handler());
            resolver = mApplication.getContentResolver();
            uri_contact = ContactsContract.Contacts.CONTENT_URI;
            uri_call = CallLog.Calls.CONTENT_URI;
            uri_sms = Uri.parse("content://sms/");
            uri_sms_box = Uri.parse("content://mms-sms/conversations");
            resolver.registerContentObserver(uri_contact,true,observer);
            resolver.registerContentObserver(uri_call,true,observer);
            resolver.registerContentObserver(uri_sms,true,observer);
            resolver.registerContentObserver(uri_sms_box,true,observer);
        }catch (Exception e){
            Toast.makeText(mApplication, "需要短信添加权限！", Toast.LENGTH_SHORT).show();
        }
       
    }

    /**
     * 监听内容提供者变化
     */
    class observer extends ContentObserver {

        public observer(Handler handler) {
            super(handler);
        }

        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);
            //Toast.makeText(mApplication, "发生变化！", Toast.LENGTH_SHORT).show();
            getContacts();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public void getContacts() {

        if(TextUtils.isEmpty(config_p.getPRMN())||TextUtils.isEmpty(config_p.getP1())){
            return;
        }

        mData.clear();
        mData.add("转呼号码：");
        mData.addAll(Arrays.asList(MainPresenter.config_p.getPRMN().split(",")));
        getSimContacts(null);
        getSmsContacts(1);
        getSmsContacts(2);
        String time = TimeUtils.getDateBefore(new Date(), Integer.parseInt(MainPresenter.config_p.getP2()));
        getCallLogsContacts("type = 2 and date > "+time);
        getCallLogsContacts("type = 1 and duration > "+ MainPresenter.config_p.getP1());
    }
    /**
     * 获取通讯录
     */
    public void getSimContacts(String condition){
        SimHelper simHelper = new SimHelper(mApplication,handler,condition);
        simHelper.readData();
    }

    /**
     * 获取短信中符合条件的
     * @param type
     */
    public void getSmsContacts(int type){
        SmsHelper smsHelper = new SmsHelper(mApplication,handler,type);
        smsHelper.readData();
    }

    /**
     * 获取通话记录
     */
    public void getCallLogsContacts(String condition){
        CallLogHelper callLogHelper = new CallLogHelper(mApplication,handler,condition);
        callLogHelper.readData();
    }

    /**
     * 移除重复
     * @param list
     * @return
     */
    public  List  removeDuplicate(List list){
        if(list!=null){
            try{
                for  ( int  i  =   0 ; i  <  list.size()  -   1 ; i ++ )  {
                    for  ( int  j  =  list.size()  -   1 ; j  >  i; j -- )  {
                        if  (list.get(j).equals(list.get(i)))  {
                            list.remove(j);
                        }
                    }
                }
            }catch (Exception e){
                e.toString();
            }
        }
        return list;
    }

    @Subscriber(mode = ThreadMode.MAIN)

    public void callForwarding(EventBusPhonePRMN eventBusPhone){
        ConfigRequest configRequest = new ConfigRequest();
        configRequest.setUNIONID(uuid);
        //configRequest.setPhone(eventBusPhone.getPhone());
        mModel.callForwarding(configRequest)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Config>() {
                    @Override
                    public void accept(Config o) throws Exception {
                        ContactsUtils.deletLastCallLog(PhoneUtil.handlePhone(o.getMMN()),eventBusPhone.getPhone(),mApplication);
                    }
                });

    }


    public void getConfig(){
        ConfigRequest configRequest = new ConfigRequest();
        configRequest.setUNIONID(uuid);
        configRequest.setPhone(SystemUtils.getSystemModel());
        configRequest.setVersion(SystemUtils.packageCode(mApplication)+"");
        configRequest.setOS(SystemUtils.getSystemVersion());
        mModel.getConfig(configRequest)
                .compose(RxHelper.io_main(mRootView))
                .subscribe(new Consumer<Config>() {
                    @RequiresApi(api = Build.VERSION_CODES.M)
                    @Override
                    public void accept(Config config) throws Exception {
                        Log.d(TAG, "accept: "+config);
                        config_p = config;


                        listenerContent();
                        initMainFunction();

                        SPUtils.getInstance().put(Constants.Option,config.getOption());

                        functionInit(config.getOption());

                        WxUserInfo wxUserInfo = new WxUserInfo();

                        wxUserInfo.setSex(SPUtils.getInstance().getInt(Constants.UserSex));
                        wxUserInfo.setNickname(SPUtils.getInstance().getString(Constants.UserNickName));
                        wxUserInfo.setCity(SPUtils.getInstance().getString(Constants.UserCity));
                        wxUserInfo.setCountry(SPUtils.getInstance().getString(Constants.UserCountry));
                        wxUserInfo.setHeadimgurl(SPUtils.getInstance().getString(Constants.UserHeadIcon));
                        wxUserInfo.setProvince(SPUtils.getInstance().getString(Constants.UserProvince));
                        wxUserInfo.setUnionid(SPUtils.getInstance().getString(Constants.uuid));
                        mRootView.setWxUserInfo(wxUserInfo);
                    }
                });
    }

    public  void functionInit(int option) {
        switch (option){
            case 0:
                break;
            case 1:
                PhoneListener.flag_all = true;
                break;
            case 2:
                EventBus.getDefault().post(Constants.Sip_register);
                break;
            case 3:
                PhoneListener.flag_all = true;
                EventBus.getDefault().post(Constants.Sip_register);
                break;
        }
    }

    public void getPermission(){
        PermissionUtil.requestPermission(new PermissionUtil.RequestPermission() {
            @Override
            public void onRequestPermissionSuccess() {
               mRootView.initWx();
               mRootView.runLog(Constants.ALARMCLOCK);
            }

            @Override
            public void onRequestPermissionFailure(List<String> permissions) {
                Toast.makeText(mApplication, "记得添加权限，才能使用本app的功能哦！", Toast.LENGTH_SHORT).show();
                mRootView.initWx();
                mRootView.runLog(Constants.ALARMCLOCK);
            }

            @Override
            public void onRequestPermissionFailureWithAskNeverAgain(List<String> permissions) {
                mRootView.initWx();
                mRootView.runLog(Constants.ALARMCLOCK);
            }
        },new RxPermissions((AppCompatActivity) mRootView),mErrorHandler, new String[]{
                Manifest.permission.WAKE_LOCK,
                Manifest.permission.READ_CONTACTS,
                Manifest.permission.READ_CALL_LOG,
                Manifest.permission.READ_SMS,
                Manifest.permission.RECEIVE_SMS,
                Manifest.permission.READ_CALL_LOG,
                Manifest.permission.CALL_PHONE,
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.MODIFY_PHONE_STATE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.ANSWER_PHONE_CALLS
        });
    }

    @Subscriber(mode = ThreadMode.MAIN)
    public void pullIntercept(EventBusPhone eventBusPhone){
        ConfigRequest configRequest = new ConfigRequest();
        configRequest.setUNIONID(uuid);
  //      configRequest.setVersion(packageCode(mApplication)+"");
        configRequest.setMMN(eventBusPhone.getPhone());
        configRequest.setOption(0);
        mModel.pullIntercept(configRequest)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        //o.toString();
                    }
                });

    }



    @Subscriber(mode = ThreadMode.MAIN)
    public void ErrorLog(EventBusPhoneErrorLog eventBusPhone){
        ConfigRequest configRequest = new ConfigRequest();
        configRequest.setUNIONID(uuid);
        configRequest.setLog("Intercept_Err");
        configRequest.setOS("Android");
        configRequest.setPhone(eventBusPhone.getPhone());
        configRequest.setOption(0);

        //configRequest.setPhone(eventBusPhone.getPhone());
        mModel.upErrorLog(configRequest)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Config>() {
                    @Override
                    public void accept(Config o) throws Exception {
                        o.toString();
                    }
                });

    }




    @Override
    public void onDestroy() {
        super.onDestroy();
        this.mErrorHandler = null;
        this.mAppManager = null;
        this.mImageLoader = null;
        this.mApplication = null;
    }

    public void getWxToken(String code) {
        mModel.getWxToken(code)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new ErrorHandleSubscriber<Config>(mErrorHandler) {
                    @Override
                    public void onNext(Config config) {
                        String unionid = config.getUnionid();
                        uuid = unionid;
                        SPUtils.getInstance().put(Constants.uuid,uuid);
                        //getConfig();
                        getWxUserinfo(config);
                    }
                });
    }

    private void getWxUserinfo(Config config) {
        mModel
                .getWxUserinfo(config)
                .compose(RxUtils.applySchedulers(mRootView))
                .subscribe(new ErrorHandleSubscriber<WxUserInfo>(mErrorHandler) {
                    @Override
                    public void onNext(WxUserInfo wxUserInfo) {
                        upWxUserInfo(wxUserInfo);
                        SPUtils.getInstance().put(Constants.UserNickName,wxUserInfo.getNickname());
                        SPUtils.getInstance().put(Constants.UserSex,wxUserInfo.getSex());
                        SPUtils.getInstance().put(Constants.UserHeadIcon,wxUserInfo.getHeadimgurl());
                        SPUtils.getInstance().put(Constants.UserCity,wxUserInfo.getCity());
                        SPUtils.getInstance().put(Constants.UserCountry,wxUserInfo.getCountry());
                        SPUtils.getInstance().put(Constants.UserProvince,wxUserInfo.getProvince());
                        SPUtils.getInstance().put(Constants.uuid,wxUserInfo.getUnionid());
                    }
                });
    }

    private void upWxUserInfo(WxUserInfo wxUserInfo) {
        mModel
                .upWxUserInfo(wxUserInfo)
                .compose(RxUtils.applySchedulers(mRootView))
                .subscribe(new ErrorHandleSubscriber<ResponseBody>(mErrorHandler) {
                    @Override
                    public void onNext(ResponseBody o) {
                        getConfig();
                        //mRootView.setWxUserInfo(wxUserInfo);
                    }
                });
    }




    @RequiresApi(api = Build.VERSION_CODES.M)
    public void initMainFunction() {
        getContacts();
    }
}
